package com.wetool.controller;

import com.wetool.entity.Merchant;
import com.wetool.entity.Shop;
import com.wetool.exception.AccountExistedException;
import com.wetool.exception.MerchantNotFoundException;
import com.wetool.exception.ParamCheckException;
import com.wetool.exception.ShopNotFoundException;
import com.wetool.model.*;
import com.wetool.model.Message.Result;
import com.wetool.model.dto.ShopInfoDto;
import com.wetool.service.MacService;
import com.wetool.service.MerchantService;
import com.wetool.service.ShopService;
import io.swagger.annotations.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import java.util.List;
import java.util.Map;

/**
 * 描述：控制器（店铺管理）
 *
 * @author zhangjie
 */
@RestController
@RequestMapping("/shop")
@RefreshScope
@Api(description = "店铺管理接口")
public class ShopController {
	private static final Logger logger = LogManager.getLogger(ShopController.class);

	@Autowired
	private MerchantService merchantService;

	@Autowired
	private ShopService shopService;

	@Autowired
	private MacService macService;

	@ApiOperation(value = "店铺列表", notes = "查询已登录商家的店铺列表", response = Message.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "page", value = "第几页", required = false, dataType = "int", paramType = "query", defaultValue = "0"),
			@ApiImplicitParam(name = "size", value = "每页行数", required = false, dataType = "int", paramType = "query", defaultValue = "20"),
			@ApiImplicitParam(name = "sort", value = "排序规则", required = false, dataType = "String", paramType = "query", defaultValue = "createDate,asc") })
	@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), @ApiResponse(code = 1, message = "操作失败！"),
			@ApiResponse(code = 6, message = "商家不存在！") })
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ResponseEntity<?> list(SearchParam param, Pageable p, PagedResourcesAssembler<Shop> assembler)
			throws MerchantNotFoundException {
		Merchant merchant = merchantService.findOne(param.getMerchantId());
		if (merchant == null) { // 根据登录用户找不到所属商家
			throw new MerchantNotFoundException();
		} else {
			param.setMerchantId(merchant.getId());
			Page<Shop> page = shopService.find(param, p);
			return new ResponseEntity<Object>(new Message<>(Result.SUCCESS, assembler.toResource(page)), HttpStatus.OK);
		}
	}
	
	/**
	 * 查询当前位置20km内距离每个店铺的距离
	 * @Param Double lon  店铺的经度
	 * @Param Double lat  店铺的纬度
	 * @Return List<ShopResult> shopResult 返回一个携带距离，经纬度和店铺信息的类的集合
	 */
		@ApiOperation(value = "店铺列表", notes = "查询目标位置与所有店铺的距离", response = Message.class)
		@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), 
								@ApiResponse(code = 1, message = "操作失败！")})
		@RequestMapping(value = "/allwithoutpage", method = RequestMethod.GET)
		public ResponseEntity<?> AllWithoutPage(SearchParam param,Pageable p)throws Exception{
			logger.info("进入接口 > 查询商家. 当前位置经度：{},当前位置纬度：{},分页：{},{}};",
					param.getLongitude(),param.getLatitude(),p.getPageNumber(),p.getSort() );
			Page<ShopInfoDto> shops = shopService.findSurroundShop(param,p);
			logger.info("接口结束 > 查询完成.");
			return ResponseEntity.ok(new Message<Page<ShopInfoDto>>(Result.SUCCESS,shops));
		}
		

	@ApiOperation(value = "店铺查询", notes = "店铺查询", response = Message.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "店铺ID", required = true, dataType = "Long", paramType = "path") })
	@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), @ApiResponse(code = 1, message = "操作失败！"),
			@ApiResponse(code = 18, message = "店铺不存在！") })
	@RequestMapping(value = "/find/{id}", method = { RequestMethod.GET })
	public ResponseEntity<Message<Shop>> find(@PathVariable Long id) throws ShopNotFoundException {
		Shop shop = shopService.findOne(id);
		if (shop == null) {
			throw new ShopNotFoundException();
		}
		return new ResponseEntity<>(new Message<Shop>(Result.SUCCESS, shop), HttpStatus.OK);
	}

	@ApiOperation(value = "店铺注册", notes = "店铺注册", response = Message.class)
	@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), @ApiResponse(code = 1, message = "操作失败！"),
			@ApiResponse(code = 2, message = "请求参数格式错误！") })
	@RequestMapping(method = RequestMethod.POST)
	public ResponseEntity<?> add(@Valid @RequestBody ShopRegister shopsRegister, BindingResult bindingResult)
			throws AccountExistedException, Exception {
		logger.info("进入接口 > 店铺注册. 参数：{}", shopsRegister);
		if (bindingResult.hasErrors()) { // 请求参数校验
			throw new ParamCheckException(bindingResult);
		}
		Shop shop = shopService.add(shopsRegister);
		Map<String, Object> map = shopService.login(shop.getId());
		logger.info("接口结束 > 店铺注册完成.");
		return new ResponseEntity<>(new Message<>(Result.SUCCESS, map), HttpStatus.CREATED);
	}

	@ApiOperation(value = "店铺修改", notes = "店铺修改", response = Message.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "店铺ID", required = true, dataType = "Long", paramType = "path") })
	@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), @ApiResponse(code = 1, message = "操作失败！"),
			@ApiResponse(code = 2, message = "请求参数格式错误！"), @ApiResponse(code = 9, message = "设备不存在！") })
	@RequestMapping(value = { "/{id}" }, method = { RequestMethod.PATCH })
	public ResponseEntity<?> modify(@NotNull(message = "{shop.id.null}") @PathVariable Long id,
			@Valid @RequestBody ShopModify shopModify, BindingResult bindingResult)
			throws ParamCheckException, ShopNotFoundException {
		logger.info("进入接口 > 店铺修改. 店铺id【{}】，参数：{}", id, shopModify);
		if (bindingResult.hasErrors()) {
			throw new ParamCheckException(bindingResult);
		}
		this.shopService.update(id, shopModify);
		logger.info("接口结束 > 店铺修改完成.");
		return new ResponseEntity<Object>(new Message<>(Message.Result.SUCCESS), HttpStatus.OK);
	}

	@ApiOperation(value = "设备绑定店铺", notes = "设备绑定店铺", response = Message.class)
	@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), @ApiResponse(code = 1, message = "操作失败！"),
			@ApiResponse(code = 2, message = "请求参数格式错误！"), @ApiResponse(code = 5, message = "无权访问！"),
			@ApiResponse(code = 9, message = "设备不存在！") })
	@RequestMapping(value = "/bind", method = RequestMethod.PATCH)
	public HttpEntity<?> bind(@Valid @RequestBody MacBind macBind, BindingResult bindingResult) throws Exception {
		logger.info("进入接口 > 设备绑定店铺. 参数：{}", macBind);
		Long shopId = macBind.getShopId();
		Shop shop = shopService.findOne(shopId);
		macService.bind(shop.getMerchant().getId(), shopId, macBind.getMacSn());
		Map<String, Object> map = shopService.login(shopId);
		logger.info("接口结束 > 设备绑定店铺.");
		return new ResponseEntity<>(new Message<>(Result.SUCCESS, map), HttpStatus.OK);
	}

	@ApiOperation(value = "店铺删除", notes = "店铺删除", response = Message.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "店铺ID", required = true, dataType = "Long", paramType = "path") })
	@ApiResponses(value = { @ApiResponse(code = 0, message = "操作成功！"), @ApiResponse(code = 1, message = "操作失败！") })
	@RequestMapping(value = { "/{id}" }, method = { RequestMethod.DELETE })
	public ResponseEntity<?> delete(@PathVariable Long id) throws ShopNotFoundException {
		logger.info("进入接口 > 店铺删除. 参数：{}", id);
		shopService.delete(id);
		logger.info("接口结束 > 店铺删除完成.");
		return new ResponseEntity<>(new Message<>(Message.Result.SUCCESS), HttpStatus.OK);
	}

	@ApiOperation(value = "店铺管理查询")
	@ApiImplicitParams({ @ApiImplicitParam(name = "merchantId", value = "商家ID", dataType = "Long", paramType = "query"),
			@ApiImplicitParam(name = "name", value = "店铺名称", dataType = "String", paramType = "query") })
	@GetMapping(value = "/item/list")
	public ResponseEntity<?> queryShopItemList(@RequestParam(required = false) Long merchantId,
			@RequestParam(required = false) String name) {

		Message<?> message = this.shopService.queryItemList(merchantId, name);

		return ResponseEntity.ok(message);
	}

	@ApiOperation(value = "店铺管理查询")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "shopId", value = "店铺ID", required = true, dataType = "Long", paramType = "path"), })
	@GetMapping(value = "/{shopId}/item")
	public ResponseEntity<?> queryShopItem(@PathVariable Long shopId) {
		Message<?> message = this.shopService.queryItem(shopId);
		return ResponseEntity.ok(message);
	}

	@ApiOperation(value = "服务商后台查询店铺管理列表", notes = "服务商后台查询店铺管理列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "page", value = "第几页", required = false, dataType = "int", paramType = "query", defaultValue = "0"),
			@ApiImplicitParam(name = "size", value = "每页行数", required = false, dataType = "int", paramType = "query", defaultValue = "20"),
			@ApiImplicitParam(name = "sort", value = "排序规则", required = false, dataType = "String", paramType = "query", defaultValue = "createDate,asc") })
	@GetMapping(value = "sp/shopList")
	public ResponseEntity<?> shopList(SearchParam param, Pageable p, PagedResourcesAssembler<Shop> assembler)
			throws MerchantNotFoundException {
		logger.info("进入接口 > 服务商后台查询店铺管理列表. 参数：{}", param);
		Page<Shop> page = shopService.find(param, p);
		logger.info("接口结束 > 服务商后台查询店铺管理列表.");
		return new ResponseEntity<Object>(new Message<>(Result.SUCCESS, assembler.toResource(page)), HttpStatus.OK);
	}
}